﻿using System;
using System.Collections.Generic;

namespace Tilver.ConsoleTest.Model
{
    /*
     建造则(Builder Pattern)也叫做生成器模式,提供一种“封装机制”来隔离出"复杂对象的各个部分"的变化,从而保持"稳健构建算法"不随着需求改变而改变。
     在建造者模式中,有如下四个角色:
     Product产品类:
        通常是实现了模板方法模式,也就是有模板方法和基本方法。
     Builder抽象建造者:
        规范产品的组建,一般是由子类实现。
     ConcreteBuilder具体建造者:
        实现抽象类定义的所有方法，并返回一个组件好的对象。
     Director导演
        负责安排已有模块的顺序，然后告诉Builder开始创建。
     * 
     * 建造者模式的实质是解耦组装过程和创建具体部件，使得我们不关心每个部件是如何组装的。
     **/
    /// <summary>
    /// 产品
    /// </summary>
    public class Product
    {
        IList<string> parts = new List<string>();
        public void Add(string str)
        {
            parts.Add(str);
        }
        public void Show()
        {
            Console.WriteLine("\n产品创建-----");
            foreach (string item in parts)
            {
                Console.WriteLine(item);
            }
        }
    }
    /// <summary>
    /// 建造者
    /// </summary>
    public abstract class Builder
    {
        public abstract void BuilderPartA();
        public abstract void BuilderPartB();
        public abstract Product GetResult();
    }
    /// <summary>
    /// 具体创建者1
    /// </summary>
    class ConcreteBuilder1 : Builder
    {
        private Product product = new Product();
        public override void BuilderPartA()
        {
            product.Add("部件A");
        }
        public override void BuilderPartB()
        {
            product.Add("部件B");
        }
        public override Product GetResult()
        {
            return product;
        }
    }
    /// <summary>
    /// 具体创建者2
    /// </summary>
    public class ConcerteBulider2 : Builder
    {
        private Product product = new Product();
        public override void BuilderPartA()
        {
            product.Add("部件X");
        }
        public override void BuilderPartB()
        {
            product.Add("部件Y");
        }
        public override Product GetResult()
        {
            return product;
        }
    }
    /// <summary>
    /// 导演
    /// </summary>
    public class Director
    {
        public void Construct(Builder builder)
        {
            builder.BuilderPartA();
            builder.BuilderPartB();
        }
    }
}
